Contents

import plotly.express as px
import pandas as pd

df = pd.read_csv('datasets/all_vaccine_data.csv')
df = df.drop(columns=['DOSES', 'TARGET_NUMBER'])
df = df.dropna()

years_sorted = sorted(df['YEAR'].unique())

fig = px.scatter(df,
                 x='COVERAGE', 
                 y='Life Expectancy', 
                 animation_frame='YEAR', 
                 animation_group='Country Name',
                 size='Child Mortality per 1000 ', 
                 color='continent', 
                 hover_name='Country Name',
                 size_max=55, 
                 range_x=[0, 100], 
                 range_y=[0, 100],
                 height=550,
                 category_orders={'YEAR': years_sorted},
                 custom_data=['Country Name', 'continent', 'Child Mortality per 1000 '])

# Update the hover template for all traces
fig.update_traces(hovertemplate="<b>%{customdata[0]}</b><br>" +
                                "<b>%{customdata[1]}</b><br><br>" +
                                "Vaccination Rate: %{x}%<br>" +
                                "Life Expectancy: %{y} years<br>" +
                                "Child Mortality per 1000: %{customdata[2]}<br>" +
                                "<extra></extra>")

# Update each frame to ensure hover template is consistent
for frame in fig.frames:
    for trace in frame.data:
        trace.hovertemplate = "<b>%{customdata[0]}</b><br>" + \
                              "<b>%{customdata[1]}</b><br><br>" + \
                              "Vaccination Rate: %{x}%<br>" + \
                              "Life Expectancy: %{y} years<br>" + \
                              "Child Mortality per 1000: %{customdata[2]}<br>" + \
                              "<extra></extra>"

fig.update_layout(
    title="Life Expectancy vs Vaccination Rates<br><sup>Child mortality declines as vaccination rate increases</sup>", title_x=0.5,
    plot_bgcolor='#cff8d6',
    paper_bgcolor='#cff8d6',
    margin={'l': 110, 'b': 220, 'r': 130, 't': 100},
    xaxis=dict(title='Vaccination Rate (%)',
               gridcolor='darkgrey',
               gridwidth=1,
               zeroline=False),   
    yaxis=dict(title='Life Expectancy in years',
               gridcolor='darkgrey',
               gridwidth=1,
               zeroline=False),
    showlegend=True,
    hovermode='closest',
    width=780,
    
    # Customize the bottom slider
    sliders=[
        {
            'active': 0,
            'yanchor': 'top',
            'xanchor': 'left',

            # Add current year display
            'currentvalue': {
                'font': {'size': 20},
                'prefix': 'Year: ',
                'visible': True,
                'xanchor': 'right'
            },
            'pad': {'b': 10, 't': 50},
            'len': 0.9,
            'x': 0.1,
            'y': 0,
            'steps': [
                {'args': [[year], {'frame': {'duration': 300, 'redraw': True}, 'mode': 'immediate'}],
                 'label': str(year),
                 'method': 'animate'} for year in years_sorted
            ],
            'transition': {'duration': 300},
            'bgcolor': '#fff', 
            'tickcolor': '#000',
        }
    ]
)

# Add caption
fig.add_annotation(x=-0.09, y=-0.89,
                   showarrow=False,
                   xref='paper', yref='paper',
                   xanchor='left', yanchor='bottom',
                   align='left',
                   text='All countries are displayed as bubbles on the graph, where a bigger bubble size corresponds to a higher child mortality.<br>' +
                   'The child mortality has a value type of deaths per 1000 children. The x-axis corresponds to the vaccination in percentages and<br>' +
                   'the y-axis to the vaccination rate of the country. Hovering over a bubble reveals which country the bubble represents.',
      font=dict(
        size=10
      ))

fig.show()